/**
 *
 * @param min: number 最小值
 * @param max: numebr 最大值(包含)
 * @returns number
 * @description 传入最小值与最大值，返回包含两端的一个随机整数
 */
export const randomInt = (min: number, max: number) => Math.round(Math.random() * (max - min) + min)

/**
 *
 * @param num: number 要转换的大额数值
 * @param float: number 要保留的浮点数个数，默认为3
 * @returns : string 处理后的结果 带"亿"或"万"单位
 * @description 把一串大额的数值转换成"x.xxx亿/万"的字符串
 */
export const localNum = (num?: number, float = 3) => {
  if (!num) return
  const size = num.toString().split('')
  let res = ''
  let ending = ''

  let i = 0
  if (size.length >= 9) {
    for (i; i < size.length - 8; i++) {
      res += size[i].toString()
    }
    ending = '亿'
    res += float > 0 ? '.' : ''
  } else if (size.length >= 5) {
    for (i; i < size.length - 4; i++) {
      res += size[i].toString()
    }
    ending = '万'
    res += float > 0 ? '.' : ''
  }

  const limit = i ? float + i : size.length
  for (i; i < limit; i++) {
    res += size[i]
  }

  return (res += ending)
}

/**
 *
 * @param time: number 出生日期时间戳
 * @returns res { astro: "xx座", offsetAge: "xx后" }
 * @description 传入一个出生日期时间戳，返回星座和年代"xx后"
 */
export const getAstroAndOffsetAge = (time: number) => {
  const res = {
    astro: '',
    offsetAge: '',
  }
  const birthday = new Date(time)

  const year = birthday.getFullYear()
  const month = birthday.getMonth() + 1
  const date = birthday.getDate()

  const offset = year % 10
  res.offsetAge =
    (year - (year % (offset >= 5 ? 5 : 10))).toString().split('').slice(2, 4).join('') + '后'

  const s = '魔羯水瓶双鱼牡羊金牛双子巨蟹狮子处女天秤天蝎射手魔羯'
  const arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
  res.astro = s.substr(month * 2 - (date < arr[month - 1] ? 2 : 0), 2) + '座'

  return res
}

type FunctionLike = (...params: any[]) => any

/**
 *
 * @param callback : 要防抖执行的回调函数
 * @param delay: number 防抖时间(ms)
 * @param useResult: boolean 默认为false不获取返回值，true时可以使用await或.then获取回调函数的返回值
 * @param _this: any 要给回调函数绑定的this指向
 * @returns db_callback : 经过防抖处理后的函数
 * @description 防抖处理后的函数连续调用时会重新计时，永远在最后一次触发的delay时间之后执行
 */
export const deBounce = <T extends FunctionLike>(
  callback: T,
  delay: number,
  useResult = false,
  _this?: any,
) => {
  let timer: number
  return (...params: Parameters<T>) => {
    if (useResult) {
      return new Promise<ReturnType<T>>((resolve) => {
        clearTimeout(timer)
        timer = window.setTimeout(() => {
          resolve(callback.bind(_this)(...params))
        }, delay)
      })
    } else {
      clearTimeout(timer)
      timer = window.setTimeout(() => {
        callback.bind(_this)(...params)
      }, delay)
      return
    }
  }
}

/**
 *
 * @param callback : 要防抖执行的回调函数
 * @param delay : number 防抖时间(ms)
 * @param useReturn : boolean 默认为false不获取返回值，true时可以使用await或.then获取回调函数的返回值
 * @returns th_callback : 经过防抖处理后的函数
 * @description 连续调用时,最短间隔时间内只会触发一次
 */
export const throttle = <T extends FunctionLike>(callback: T, delay: number, useReturn = false) => {
  //函数立即触发并计时，在delay时间内不会触发，但最后一次一定会在delay时间后执行
  //也就是一直点击一直触发，但每次触发都会有最小间隔时间delay
  let lastTime: number, nowTime: number, timer: number
  return (...params: Parameters<T>) => {
    if (useReturn) {
      return new Promise<ReturnType<T>>((resolve) => {
        nowTime = Date.now() // 当前触发事件的时间（毫秒）
        if (lastTime && nowTime < lastTime + delay) {
          clearTimeout(timer)
          timer = window.setTimeout(function () {
            lastTime = nowTime
            resolve(callback(...params))
          }, delay)
        } else {
          lastTime = nowTime
          resolve(callback(...params))
        }
      })
    }
    nowTime = Date.now() // 当前触发事件的时间（毫秒）
    if (lastTime && nowTime < lastTime + delay) {
      clearTimeout(timer)
      timer = window.setTimeout(function () {
        lastTime = nowTime
        callback(...params)
      }, delay)
    } else {
      lastTime = nowTime
      callback(...params)
    }
  }
}

/**
 *
 * @param arr: Array<any> 要处理的目标数组
 * @param target: any 要删除的元素值
 * @description 删除数组中的首个目标元素，成功返回删除项，失败返回undefined
 */
export const removeArrItem = (arr: any[], target: any) => {
  const targetIndex = arr.indexOf(target)
  if (targetIndex === -1) return
  return arr.splice(targetIndex, 1)[0]
}

export const formatImgUrl = (url: string) => {
  let res = url
  res = res.replace(/^(http)[s]*(\:\/\/)/, 'https://images.weserv.nl/?url=')
  return res
}
